static int blecent_gap_event(struct ble_gap_event *event, void *arg)
{
    struct ble_gap_conn_desc desc;
    int rc;
    struct ble_hs_adv_fields fields;
    app_bridged_device_t *device;
    uint8_t espnow_macaddr[6];

    switch (event->type)
    {

    case BLE_GAP_EVENT_DISC:
        espnow_macaddr[0] = event->disc.addr.val[5];
        espnow_macaddr[1] = event->disc.addr.val[4];
        espnow_macaddr[2] = event->disc.addr.val[3];
        espnow_macaddr[3] = event->disc.addr.val[2];
        espnow_macaddr[4] = event->disc.addr.val[1];
        espnow_macaddr[5] = event->disc.addr.val[0];
        device = app_bridge_get_device_by_espnow_macaddr(espnow_macaddr);
        /*
        if(device){
            ESP_LOGE(TAG, "Found Device (bda): %02x:%02x:%02x:%02x:%02x:%02x", event->disc.addr.val[5],\
                event->disc.addr.val[4],event->disc.addr.val[3],event->disc.addr.val[2],event->disc.addr.val[1],event->disc.addr.val[0]);
            esp_log_buffer_hex(TAG,event->disc.data,event->disc.length_data);
        }
        */

       // 筛选出广播名称为  PGH260TEST 的从机  ， 获取它的 rssi
        char device_name[32];
        get_peripheral_device_name(event->disc.data, event->disc.length_data, device_name, sizeof(device_name));

        if (device_name[0] != '\0')
        {

            ESP_LOGI(TAG, "scan the lock ble signal the name = %s and the rssi = %d\r\n", device_name, event->disc.rssi);
        }

        rc = ble_hs_adv_parse_fields(&fields, event->disc.data,
                                     event->disc.length_data);

        if ((EventCache.src) && (EventCache.src->bindHubAndLockRequest.cacheActive == true))
        {

            EventCache.src->bindHubAndLockRequest.cacheActive = false;

            EventCache.src->status = ESP_FAIL;          
            EventCache.src->code = MqttErrCode_DeviceNotFound;

            app_bridged_device_info_t bridged_device_info;
            memset(&bridged_device_info, 0, sizeof(app_bridged_device_info_t));

            // ESP_LOGI(TAG,"the deviceLabel ble cent = %s",EventCache.src->bindHubAndLockRequest.deviceLabel);

            if ((fields.name != NULL) && (!strcmp(EventCache.src->bindHubAndLockRequest.deviceLabel, fields.name)))
            {
                printf("Device name: %.*s\n", fields.name_len, fields.name);
            }
        }

        if (event->disc.event_type == BLE_HCI_ADV_RPT_EVTYPE_SCAN_RSP)
        {
            struct ble_hs_adv_fields fields;
            rc = ble_hs_adv_parse_fields(&fields,event->disc.data,event->disc.length_data);
            if (rc != 0)
                return;

            if ((fields.name != NULL) && (!memcmp(fields.name, LOCK_NAMEss, fields.name_len)))
            {
                ESP_LOGW(TAG, "get the  target");
                printf("ScanRsp Name: %.*s\n", fields.name_len, fields.name);
            }
        }


        if (rc != 0)
        {
            if (device)
                ESP_LOGE(TAG, "Failed to parse advertisement data; rc=%d\n", rc);
            return 0;
        } 
        if (fields.mfg_data_len > 16)
        {
            if (device)
            {
                device->dev_info.rssi = event->disc.rssi;
                if ((device->dev_info.is_online == false) || (get_timestamp_ms() - device->dev_info.last_update_time > 120000))
                {
                    device->dev_info.is_online = true;
                    DeviceLayer::PlatformMgr().ScheduleWork(UpdateLockReachableAttribute, reinterpret_cast<intptr_t>(device));
                    GetAppTask().AppScheduleWork(PublishOnlineStatus, reinterpret_cast<intptr_t>(device));
                }
                device->dev_info.last_update_time = get_timestamp_ms();
                if (fields.mfg_data[2] == 19)
                {
                    if (fields.mfg_data[21] == 1)
                    {
                        GetAppTask().AppScheduleWork(SendLockSyncTimeCommand, reinterpret_cast<intptr_t>(device));
                    }
                }

                if (memcmp(device->dev_info.ble_broadcast_data, fields.mfg_data, fields.mfg_data_len))
                {
                    // ESP_LOGE(TAG, "Device address (bda): %02x:%02x:%02x:%02x:%02x:%02x", event->disc.addr.val[5],
                    //          event->disc.addr.val[4], event->disc.addr.val[3], event->disc.addr.val[2], event->disc.addr.val[1], event->disc.addr.val[0]);
                    // ESP_LOGI(TAG, "manufacture_data_len = %d", fields.mfg_data_len);
                    esp_log_buffer_hex(TAG, fields.mfg_data, fields.mfg_data_len);
                    device->dev_info.change_bit = 0;
                    if (device->dev_info.device_status != fields.mfg_data[3])
                    {
                        if ((device->dev_info.device_status & 0x01) != (fields.mfg_data[3] & 0x01))
                            device->dev_info.change_bit |= DoorLockStatusBit;
                        device->dev_info.last_change_time = get_timestamp_ms();
                        if (fields.mfg_data[3] & 0x02)
                        {
                            // to do .. find the wired sensor firstly
                            app_bridged_device_t *sensor = app_bridge_get_sensor_by_sensor_id("FFFFFF");
                            if ((sensor) && ((device->dev_info.device_status & 0x04) != (fields.mfg_data[3] & 0x04)))
                            {
                                if (fields.mfg_data[3] & 0x04)
                                    sensor->dev_info.sensor_status = 1;
                                else
                                    sensor->dev_info.sensor_status = 2;
                                sensor->dev_info.last_change_time = get_timestamp_ms();
                                if (ENABLE_HOMEKIT_SENSOR)
                                    DeviceLayer::PlatformMgr().ScheduleWork(UpdateDoorSensorAttribute, reinterpret_cast<intptr_t>(sensor));
                                else
                                    ESP_LOGE(TAG, "Sensor status is %d, HOMEKIT sesnor function is disabled.", sensor->dev_info.sensor_status);

                                device->dev_info.change_bit |= DoorLockStatusBit;
                                if (sensor->dev_info.is_online == false)
                                {
                                    sensor->dev_info.is_online = true;
                                    DeviceLayer::PlatformMgr().ScheduleWork(UpdateLockReachableAttribute, reinterpret_cast<intptr_t>(sensor));
                                }
                            }
                        }

                        ESP_LOGE(TAG, "Device address (bda): %02x:%02x:%02x:%02x:%02x:%02x", event->disc.addr.val[5],
                                 event->disc.addr.val[4], event->disc.addr.val[3], event->disc.addr.val[2], event->disc.addr.val[1], event->disc.addr.val[0]);
                        ESP_LOGE(TAG, "Old Status:%02x, New Status:%02x", device->dev_info.device_status, fields.mfg_data[3]);

                        if (((device->dev_info.device_status & (SECURE_MODE_BIT | SECURE_MODE_BIT)) != (fields.mfg_data[3] & (SECURE_MODE_BIT | SECURE_MODE_BIT))) || ((device->dev_info.device_status & LOW_BAT_BIT) != (fields.mfg_data[3] & LOW_BAT_BIT)))
                        {
                            if (fields.mfg_data[3] & (SECURE_MODE_BIT | SECURE_MODE_BIT))
                                ESP_LOGE(TAG, "Secure Mode is on");
                            else
                                ESP_LOGE(TAG, "Secure Mode is off");

                            if (fields.mfg_data[3] & (LOW_BAT_BIT))
                            {
                                ESP_LOGE(TAG, "Low Battery");
                            }
                            else
                            {
                                ESP_LOGE(TAG, "Battery is normal");
                            }
                            device->dev_info.change_bit |= DoorLockStatusBit;
                        }

                        if ((device->dev_info.device_status & 0x01) != (fields.mfg_data[3] & 0x01))
                        {
                            device->dev_info.device_status = fields.mfg_data[3];
                            device->dev_info.reserve[0] = 0;
                            device->dev_info.reserve[0] = 0;
                            device->dev_info.reserve[0] = 0;
                            DeviceLayer::PlatformMgr().ScheduleWork(UpdateLockAttribute, reinterpret_cast<intptr_t>(device));
                        }
                        else
                            device->dev_info.device_status = fields.mfg_data[3];
                    }
                    if (memcmp(&device->dev_info.ble_broadcast_data[4], &fields.mfg_data[4], fields.mfg_data_len - 4))
                    {
                        device->dev_info.change_bit |= DoorlockEventBit;
                    }
                    memcpy(device->dev_info.ble_broadcast_data, fields.mfg_data, fields.mfg_data_len);
                    if (device->dev_info.change_bit)
                        GetAppTask().AppScheduleWork(PublishDoorLockStatus, reinterpret_cast<intptr_t>(device));
                }
                else
                {
                /*
                    ESP_LOGE(TAG, "Data No Change: Device address (bda): %02x:%02x:%02x:%02x:%02x:%02x", event->disc.addr.val[5],
                             event->disc.addr.val[4], event->disc.addr.val[3], event->disc.addr.val[2], event->disc.addr.val[1], event->disc.addr.val[0]);
                    esp_log_buffer_hex(TAG, fields.mfg_data, fields.mfg_data_len);
                */
                }
            }
        }
        else
        {
            // ESP_LOGE(TAG, "No manufacture data");
            app_bridged_device_t *device;
            uint8_t espnow_macaddr[6];
            espnow_macaddr[0] = event->disc.addr.val[5];
            espnow_macaddr[1] = event->disc.addr.val[4];
            espnow_macaddr[2] = event->disc.addr.val[3];
            espnow_macaddr[3] = event->disc.addr.val[2];
            espnow_macaddr[4] = event->disc.addr.val[1];
            espnow_macaddr[5] = event->disc.addr.val[0];
            device = app_bridge_get_device_by_espnow_macaddr(espnow_macaddr);
            if (device)
            {
                device->dev_info.rssi = event->disc.rssi;
                if ((device->dev_info.is_online == false) || (get_timestamp_ms() - device->dev_info.last_update_time > 120000))
                {
                    device->dev_info.is_online = true;
                    DeviceLayer::PlatformMgr().ScheduleWork(UpdateLockReachableAttribute, reinterpret_cast<intptr_t>(device));
                    GetAppTask().AppScheduleWork(PublishOnlineStatus, reinterpret_cast<intptr_t>(device));
                }
                device->dev_info.last_update_time = get_timestamp_ms();
            }
        }
        return 0;
        case BLE_GAP_EVENT_DISCONNECT:
        /* Connection terminated. */
        MODLOG_DFLT(INFO, "disconnect; reason=%d ", event->disconnect.reason);
        print_conn_desc(&event->disconnect.conn);
        MODLOG_DFLT(INFO, "\n");

        /* Forget about peer. */
        peer_delete(event->disconnect.conn.conn_handle);

        /* Resume scanning. */
        blecent_scan();
        connectedFlag = false;
        g_cen_conn_handle = 0xff;
        return 0;

    case BLE_GAP_EVENT_CONNECT:
        /* A new connection was established or a connection attempt failed. */
        if (event->connect.status == 0) {
            /* Connection successfully established. */
            g_cen_conn_handle = event->connect.conn_handle;
            MODLOG_DFLT(INFO, "Connection established g_cen_conn_handle = %d",g_cen_conn_handle);

            rc = ble_gap_conn_find(event->connect.conn_handle, &desc);
            assert(rc == 0);
            print_conn_desc(&desc);
            MODLOG_DFLT(INFO, "\n");

            /* Remember peer. */
            rc = peer_add(event->connect.conn_handle);
            if (rc != 0) {
                MODLOG_DFLT(ERROR, "Failed to add peer; rc=%d\n", rc);
                return 0;
            }
            
            /* Perform service discovery */
            rc = peer_disc_all(event->connect.conn_handle,
                        blecent_on_disc_complete, arg);
            if(rc != 0) {
                MODLOG_DFLT(ERROR, "Failed to discover services; rc=%d\n", rc);
                return 0;
            }
        } else {
            /* Connection attempt failed; resume scanning. */
            MODLOG_DFLT(ERROR, "Error: Connection failed; status=%d\n",
                        event->connect.status);
            blecent_scan();
        }

        return 0;
    case BLE_GAP_EVENT_NOTIFY_RX:
        /* Peer sent us a notification or indication. */
        MODLOG_DFLT(INFO, "received %s; conn_handle=%d attr_handle=%d "
                          "attr_len=%d\n",
                    event->notify_rx.indication ? "indication" : "notification",
                    event->notify_rx.conn_handle,
                    event->notify_rx.attr_handle,
                    OS_MBUF_PKTLEN(event->notify_rx.om));

        /* Attribute data is contained in event->notify_rx.om. Use
         * `os_mbuf_copydata` to copy the data received in notification mbuf */
        // 接收到从机 的 数据
        esp_log_buffer_hex("yuezheng.gao received data form pher", event->notify_rx.om->om_data, event->notify_rx.om->om_len);

        // 连接确认,收到唤醒指令应答，表示连接正常
        if(!memcmp(event->notify_rx.om->om_data,weak_up_instruction_ack,8))
        {
            connectedFlag = true;
            ESP_LOGI("after connected", " g_cen_conn_handle = %d, ble_gap_conn_active = %d connectedFlag = %d", g_cen_conn_handle, ble_gap_conn_active(), connectedFlag);

            printf("Received weak_up_instruction_ack data (%d bytes):\n", event->notify_rx.om->om_len);
            for (int i = 0; i < event->notify_rx.om->om_len; i++)
            {
                printf("%02X ", event->notify_rx.om->om_data[i]);
            }
            printf("\r\n");

            esp_err_t err = esp_timer_start_once(one_shot_timer, 8000 * 1000);
            if (err != ESP_OK)
            {
                err = esp_timer_restart(one_shot_timer, 8000 * 1000);
                if (err != ESP_OK)
                {
                    ESP_LOGE(TAG, "Failed to esp_timer_restart timer: %s", esp_err_to_name(err));
                    return;
                }
            }
        }
        else // 非唤醒指令应答，业务逻辑处理
        {
            // 组包处理
            static uint16_t total_packet_len;
            static uint16_t offset = 0;
            static uint8_t total_ble_msg[256];

            if (!memcmp(event->notify_rx.om->om_data, BLE_HEAD, 4))
            {
                // 获取 ble 接收到的数据 总长度
                total_packet_len = ((uint16_t)event->notify_rx.om->om_data[5] << 8) | event->notify_rx.om->om_data[4];
            }

            if (total_packet_len > 0)
            {
                uint8_t one_pack_len = event->notify_rx.om->om_len;
                uint8_t *one_pack_data = event->notify_rx.om->om_data;
                memcpy(&total_ble_msg[offset], one_pack_data, one_pack_len);
                offset += one_pack_len;

                if (offset >= total_packet_len)
                {
                    process_complete_data(total_ble_msg, total_packet_len);
                    // 复位 数据缓存区 ，数据总长，数据偏移位置。
                    memset(total_ble_msg, 0x00, sizeof(total_ble_msg));
                    total_packet_len = 0;
                    offset = 0;
                }
            }
        }

    default:
        return 0;
    }
}










// 解析广播数据，提取蓝牙名称
static void get_peripheral_device_name(const uint8_t *adv_data, uint8_t adv_len, char *buffer, size_t buffer_size) {
    int index = 0;

    // 清空缓冲区
    if (buffer_size > 0) {
        buffer[0] = '\0';
    }

    while (index < adv_len) {
        uint8_t length = adv_data[index];
        uint8_t type = adv_data[index + 1];

        if (length == 0) {
            break;
        }

        // 检查广播数据类型
        if (type == BLE_HS_ADV_TYPE_COMP_NAME) {
            size_t name_length = length - 1; // 名称长度
            if (name_length >= buffer_size) {
                name_length = buffer_size - 1; // 限制长度，避免缓冲区溢出
            }
            memcpy(buffer, &adv_data[index + 2], name_length);
            buffer[name_length] = '\0'; // 确保以 '\0' 结尾
            return; // 找到名称后立即返回
        }

        index += length + 1; // 跳到下一个字段
    }

    // 未找到名称，缓冲区已经清空
}